package com.ylz.sjzx.sio.room.repository;

import cn.hutool.core.util.StrUtil;
import com.corundumstudio.socketio.SocketIOClient;
import com.ylz.sjzx.sio.common.mid.cache.redis.JedisTemplate;
import com.ylz.sjzx.sio.common.core.constant.Const;
import com.ylz.sjzx.sio.common.core.enums.SocketModel;
import com.ylz.sjzx.sio.sdk.client.core.IMNioBase;
import com.ylz.sjzx.sio.sdk.client.session.IMSession;
import io.netty.channel.Channel;
import lombok.SneakyThrows;

import java.util.Arrays;
import java.util.Objects;

/*
 * 正式场景下，使用redis或者数据库来存储session信息
 */
public final class SessionRepository {

    @SneakyThrows
    public static void save(IMSession session) {
        JedisTemplate.me().hSet(Const.SESSION, session.getSid(), session, Const.ROOMEXPIRE);

        if (!session.isMpFlag()) {
            //非推流端
            //userId 关联sessionId
            setUserSession(session);
        }

    }

    @SneakyThrows
    public static IMSession getSid(String sid) {

        IMSession imSession = JedisTemplate.me().hashGet(Const.SESSION, sid, IMSession.class);

        return setSocket(imSession);
    }

    /**
     * 从登录列表
     *
     * @param closeSession
     */
    @SneakyThrows
    public static void removeOnlineList(IMSession closeSession) {
        JedisTemplate.me()
                .hashDel(Const.PREFIX_YKT + closeSession.getRoomName() + ":onlineList",
                        Arrays.asList(closeSession.getUserId().toString()));
    }

    @SneakyThrows
    public static void remove(IMSession closeSession) {
        if (closeSession != null) {
            String saveSid = getSidByUserId(closeSession.getRoomName(), closeSession.getUserId());
            //防止删除错误 有且只有一个登录
            if (Objects.equals(closeSession.getSid(), saveSid) && !closeSession.isMpFlag()) {
                //非推流端
                JedisTemplate.me().hashDel(Const.USER_SESSION + closeSession.getRoomName(),
                        Arrays.asList(closeSession.getUserId().toString()));
                //从登录列表删除
                SessionRepository.removeOnlineList(closeSession);

                //redis从聊天室组中移除
                RoomRepository.removeFromRoomGroup(closeSession);
            }
            JedisTemplate.me().hashDel(Const.SESSION, Arrays.asList(closeSession.getSid()));
        }
    }

    @SneakyThrows
    public static IMSession getByUserId(String roomName, String userId) {
        String sid = getSidByUserId(roomName, userId);
        if (StrUtil.isBlank(sid)) {
            return null;
        }
        return getSid(sid);
    }

    @SneakyThrows
    public static void setUserSession(IMSession session) {
        JedisTemplate.me()
                .hSet(Const.USER_SESSION + session.getRoomName(), session.getUserId().toString(), session.getSid(),
                        Const.ROOMEXPIRE);
    }

    @SneakyThrows
    public static String getSidByUserId(String roomName, String userId) {
        return JedisTemplate.me().hashGet(Const.USER_SESSION + roomName, userId, String.class);
    }

    /**
     * 临时用户信息
     *
     * @param sid
     * @return
     */
    @SneakyThrows
    public static IMSession getSidTemp(String sid) {
        IMSession imTempSession = JedisTemplate.me().get(Const.SESSION + ":" + Const.TEMP + sid, IMSession.class);
        return setSocket(imTempSession);
    }

    /**
     * 临时缓存10分钟
     *
     * @param session
     */
    @SneakyThrows
    public static void saveTemp(IMSession session) {
        JedisTemplate.me().set(Const.SESSION + ":" + Const.TEMP + session.getSid(), session, 600);
        //userId 关联sessionId
        JedisTemplate.me().set(Const.USER_SESSION + Const.TEMP + session.getRoomName() + ":" + session.getUserId(),
                session.getSid(), 600);
    }

    /**
     * 删除临时用户
     *
     * @param session
     */
    @SneakyThrows
    public static void removeTemp(IMSession session) {
        JedisTemplate.me().delKey(Const.SESSION + ":" + Const.TEMP + session.getSid());
        //userId 关联sessionId
        JedisTemplate.me().delKey(Const.USER_SESSION + Const.TEMP + session.getRoomName() + ":" + session.getUserId());
    }

    private static IMSession setSocket(IMSession imSession) {
        if (imSession == null) {
            return imSession;
        }
        if (Objects.equals(SocketModel.channel, imSession.getSocketModel())) {
            //处理channel 事件
            Channel channel = IMNioBase.getGlobalChannel().get(imSession.getSid());
            if (channel != null) {
                imSession.setChannel(channel);
            }
        } else {
            SocketIOClient socketIOClient = IMNioBase.getSocketIOClientMap().get(imSession.getSid());
            if (socketIOClient != null) {
                imSession.setSocketIOClient(socketIOClient);
            }
        }
        return imSession;
    }
}
